package com.iflytek.cosmo.ocr.common.utils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Scanner;

import cn.hutool.core.util.StrUtil;

/**
 * 机器信息提取
 *
 * @author <a href=mailto:ktyi@iflytek.com>伊开堂</a>
 * @date 2021/8/2
 */
public class ComputerIdentifierExtractor {
    private static final String UNKNOWN = "unknown";

    private static final String OS = System.getProperty("os.name").toLowerCase();

    public static String get() {
        try {
            if (isWindows()) {
                return getWindowsIdentifier();
            }
            else if (isMac()) {
                return getMacOsIdentifier();
            }
            else if (isLinux()) {
                return getLinuxMachinedId();
            }
            else {
                return UNKNOWN;
            }
        }
        catch (Exception e) {
            return UNKNOWN;
        }
    }

    private static boolean isWindows() {
        return OS.contains("win");
    }

    private static boolean isMac() {
        return OS.contains("mac");
    }

    private static boolean isLinux() {
        return OS.contains("inux");
    }

    /**
     * 读取linux系统的machineId信息
     * @return
     * @throws FileNotFoundException
     * @throws NoSuchAlgorithmException
     */
    public static String getLinuxMachinedId() throws FileNotFoundException, NoSuchAlgorithmException {
        File machineId = new File("/var/lib/dbus/machine-id");
        if (!machineId.exists()) {
            machineId = new File("/etc/machine-id");
        }
        if (!machineId.exists()) {
            return UNKNOWN;
        }

        Scanner scanner = null;
        try {
            scanner = new Scanner(machineId);
            String id = scanner.useDelimiter("\\A").next();
            return StrUtil.trim(id);
        }
        finally {
            if (scanner != null) {
                scanner.close();
            }
        }
    }

    public static String getMacOsIdentifier() throws SocketException, NoSuchAlgorithmException {
        NetworkInterface networkInterface = NetworkInterface.getByName("en0");
        byte[] hardwareAddress = networkInterface.getHardwareAddress();
        return new String(hardwareAddress);
    }

    public static String getWindowsIdentifier() throws IOException, NoSuchAlgorithmException {
        Runtime runtime = Runtime.getRuntime();
        Process process = runtime.exec(new String[]{"wmic", "csproduct", "get", "UUID"});

        String result = null;
        InputStream is = process.getInputStream();
        Scanner sc = new Scanner(process.getInputStream());
        try {
            while (sc.hasNext()) {
                String next = sc.next();
                if (next.contains("UUID")) {
                    result = sc.next().trim();
                    break;
                }
            }
        }
        finally {
            is.close();
        }

        return result == null ? UNKNOWN : result;
    }

    /**
     * 获取mac地址
     * @return
     * @throws SocketException
     */
    public static List<String> readMacList() throws SocketException {
        List<String> macList = new ArrayList<>();
        Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
        while (networkInterfaces.hasMoreElements()) {
            NetworkInterface ni = networkInterfaces.nextElement();

            byte[] hardwareAddress = ni.getHardwareAddress();
            if (hardwareAddress == null) {
            } else {
                String[] hexadecimalFormat = new String[hardwareAddress.length];
                for (int i = 0; i < hardwareAddress.length; i++) {
                    hexadecimalFormat[i] = String.format("%02X", hardwareAddress[i]);
                }
                macList.add(String.join("", hexadecimalFormat).toLowerCase());
            }
        }
        return macList;
    }

    /**
     * 通过本地命令读取linux系统的mac地址
     * @return
     */
    public static List<String> readLinuxMacAddressByCommand() {
        List<String> macList = new ArrayList<>();
        String command = "ifconfig -a | grep ether | awk '{print $2}' | uniq";
        Process p = null;
        try {
            p = Runtime.getRuntime().exec(command);
            BufferedReader inn = new BufferedReader(new InputStreamReader(p.getInputStream()));
            while (true) {
                String line = inn.readLine();
                if (line == null) {
                    break;
                }
                macList.add(line.toLowerCase());
            }
        }
        catch (Exception e) {
            System.out.println("读取Linux MAC信息异常, " + e.getMessage());
        }

        return macList;
    }
}
